package com.wn.sk.member.core.service.impl;

import cn.hutool.crypto.digest.BCrypt;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.wn.common.api.status.impl.BusinessCode;
import com.wn.sk.common.jwt.JwtTemplate;
import com.wn.sk.member.core.dto.UserDto;
import com.wn.sk.member.core.entity.User;
import com.wn.sk.member.core.exception.LoginException;
import com.wn.sk.member.core.mapper.UserMapper;
import com.wn.sk.member.core.service.IUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 会员用户表 服务实现类
 * </p>
 *
 * @author Yellow Docker
 * @since 2022-09-06
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    private JwtTemplate jwtTemplate;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     *
     * 用户认证流程:
     *  1. 根据手机号码查询用户
     *  2. 判断用户和密码
     *  3. 校验成功生成token  ( 登录成功要把 用户信息存储到session中 )
     *  4. token的值存储到redis中
     *  5. 返回token
     *
     * @param userDto
     * @return
     */
    @Override
    public String login(UserDto userDto) throws Exception {

        //01 通过手机 查询
        //根据 Wrapper，查询一条记录
        LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery();
        //条件 mobile
        wrapper.eq(User::getUserMobile,userDto.getMobile());
        User user = this.getOne(wrapper);

        //02 判断
        if (ObjectUtils.isNull(user)) { //判断是否为null
            throw new LoginException("login error");
        }

        //判断密码
        // userDto.getPassword() 是前端传递过来的明文密码
        // user.getPayPassword() 数控中存储的加密的密码
        if (!BCrypt.checkpw(userDto.getPassword(),user.getLoginPassword())) { //判断是否为null
            throw new LoginException("login error");
        }

        //3 生产token
        Map<String,Object> map = new HashMap<>();

        map.put("userId",user.getUserId());
        String token = jwtTemplate.createToken(map);

        // 把 4 token 存储到redis中

        //项目:业务:id
        stringRedisTemplate.opsForValue().set(
                "sk:member:"+user.getUserId(),
                token,
                30,
                TimeUnit.MINUTES
        );

        return token;
    }

    public static void main(String[] args) {

        //hutool中有工具
        // BCrypt 这个工具 可以 获取盐
        String salt = BCrypt.gensalt();
        System.out.println("gensalt = " + salt);

        //可以进行加密
        String pwdStr = BCrypt.hashpw("123456", salt);
        System.out.println("pwdStr = " + pwdStr);

        //密码比对的 方法
        // 参数1： 第二个参数  加密后的密码
        boolean checkpw = BCrypt.checkpw("13456", pwdStr);
        System.out.println("checkpw = " + checkpw);

        //$10$DjiBwXxHfNfMoCwmIZ0OUOEuHzHXV9BgHqa2MkgKXRN0ESKwbLN76
        //$10$6u1hxR9hmGQwfOsavVcqMOjzSywvLysqOVwQChQxdF30W0Y8EgZky
        boolean checkpw2 = BCrypt.checkpw("123456", "$2a$10$DjiBwXxHfNfMoCwmIZ0OUOEuHzHXV9BgHqa2MkgKXRN0ESKwbLN76");
        System.out.println("checkpw2 = " + checkpw2);
    }
}
